#include "users_login.h"

#include "struct_tlv.h"

#include "log.h"

int usersLogin(userOpInfo_t *useropinfo) {
	MYSQL *conn = useropinfo->mysql;
	int netfd = useropinfo->netfd;
	tlvPacket_t packet;
	memset(&packet, 0, sizeof(tlvPacket_t));

	int ret;
	commandType_t type;
	char userName[1024] = {0};
	int userDeleteFlag;//已存在用户的is_deleted
	char query[4096];//mysql命令字符串
	MYSQL_RES *res;
	MYSQL_ROW row;//获取的行值
	char encryptedPassWord[1024] = {0};//定义密文

	while (1) {
		//接收用户名和type
		ret = recv(netfd, &packet.type, sizeof(packet.type), MSG_WAITALL);
		if (ret == 0) {
			return -1;
		}
		type = packet.type;
		ret = recv(netfd, &packet.length, sizeof(packet.length), MSG_WAITALL);
		if (ret == 0) {
			return -1;
		}
		ret = recv(netfd, packet.value, packet.length, MSG_WAITALL);
		if (ret == 0) {
			return -1;
		}
		memcpy(userName, packet.value, packet.length);

		//注册业务退出循环
		if (type == REGISTER) {
			break;
		}

		//在用户表中查询用户是否存在
		memset(query, 0, sizeof(query));
		int existsUser = 1;//1用户默认存在
		snprintf(query, sizeof(query), "SELECT is_deleted FROM user_info WHERE username = '%s'", userName);

		//执行查询
		if (mysql_query(conn, query)) {
			fprintf(stderr, "mysql_query failed:%s\n", mysql_error(conn));
			return -1;
		}

		//获取结果
		res = mysql_store_result(conn);
		if (!res) {
			if (mysql_error(conn)) {
				fprintf(stderr, "获取结果失败：%s\n", mysql_error(conn));
				return -1;
			} else {
				printf("不是select\n");
			}
		} else {
			row = mysql_fetch_row(res);
			if (row != NULL) {
				userDeleteFlag = atoi(row[0]);//为一存在已删用户
				if (userDeleteFlag == 1) {
					existsUser = 0;
				} else {
					existsUser = 1;
				}

			} else {
				existsUser = 0;
				fprintf(stderr, "警告: user不存在为空\n");
			}
		}

		mysql_free_result(res);

		//给client发送是否存在该用户
		send(netfd, &existsUser, sizeof(int), MSG_NOSIGNAL);
		//printf("existsUser = %d\n",existsUser);
		if (existsUser == 1) break;
	}

	//返回给调用者所需参数,修改useropinfo结构体
	memcpy(useropinfo->userName, userName, sizeof(useropinfo->userName)); //返回用户名

	char*salt;
	char output[CRYPT_GENSALT_OUTPUT_SIZE] = {0};
	if (type == REGISTER) {
		//生成salt
		salt = crypt_gensalt_r("$y$", 0, NULL, 0, output, sizeof(output));
		ERROR_CHECK(salt, NULL, "crypt_gensalt_r");
	} else {
		//获取salt
		memset(query, 0, sizeof(query));
		snprintf(query, sizeof(query), "SELECT salt FROM user_info WHERE username = '%s'", userName);
		if (mysql_query(conn, query)) {
			fprintf(stderr, "查找失败：%s\n", mysql_error(conn));
			mysql_close(conn);
			return -1;
		}
		res = mysql_store_result(conn);
		if (!res) {
			fprintf(stderr, "row获取结果失败: %s\n", mysql_error(conn));
		}
		row = mysql_fetch_row(res);
		if (!row) {
			fprintf(stderr, "row获取结果失败: %s\n", mysql_error(conn));
		}
		memcpy(output, row[0], sizeof(output));
		salt = output;
	}
	//发送salt
	memset(&packet, 0, sizeof(packet));
	packet.length = strlen(salt) +1;
	memcpy(packet.value, salt, packet.length);
	send(netfd, &packet, sizeof(packet.type)
	     + sizeof(packet.length) + packet.length, MSG_NOSIGNAL);

	//注册
	if (type == REGISTER) {
		//接收密文
		ret = recv(netfd, &packet.type, sizeof(packet.type), MSG_WAITALL);
		if (ret == 0) {
			printf("ret = 0, client已退出！\n");
			return -1;
		}
		ret = recv(netfd, &packet.length, sizeof(packet.length), MSG_WAITALL);
		if (ret == 0) {
			printf("ret = 0, client已退出！\n");
			return -1;
		}
		ret = recv(netfd, packet.value, packet.length, MSG_WAITALL);
		if (ret == 0) {
			printf("ret = 0, client已退出！\n");
			return -1;
		}
		memcpy(encryptedPassWord, packet.value, packet.length);

		int success = 1;
		//存在delete的同名用户，更改信息注册
		if (userDeleteFlag == 1) {
			snprintf(query, sizeof(query), "UPDATE user_info SET is_deleted = 0 WHERE username='%s'", userName);
			if (mysql_query(conn, query)) {
				success = -1;
				send(netfd, &success, sizeof(int), MSG_NOSIGNAL);
				fprintf(stderr, "插入失败：%s\n", mysql_error(conn));
				mysql_close(conn);
				return -1;
			}
			int result = mysql_affected_rows(conn);
			if (result == -1) {
				success = -1;
				send(netfd, &success, sizeof(int), MSG_NOSIGNAL);
				fprintf(stderr, "set错误: %s\n", mysql_error(conn));
				return -1;
			}
			printf("新用户成功修改用户表\n");
			send(netfd, &success, sizeof(int), MSG_NOSIGNAL);
		}
		//新用户插入用户表
		else {
			int is_deleted = 0;
			memset(query, 0, sizeof(query));
			snprintf(query, sizeof(query),
			         "INSERT INTO user_info (username,salt,encrypted_password,is_deleted)"
			         "VALUES('%s','%s','%s','%d')",
			         userName, salt, encryptedPassWord, is_deleted);

			//执行查询语句
			if (mysql_query(conn, query)) {
				success = -1;
				send(netfd, &success, sizeof(int), MSG_NOSIGNAL); //发送注册失败的信息
				fprintf(stderr, "插入失败：%s\n", mysql_error(conn));
				mysql_close(conn);
				return -1;
			}
			printf("新用户成功插入用户表\n");
			send(netfd, &success, sizeof(int), MSG_NOSIGNAL);
		}
		//注册初始化文件表
		memset(query, 0, sizeof(query));
		snprintf(query, sizeof(query),
		         "INSERT INTO file_info (username)"
		         "VALUES('%s')",
		         userName);
		if (mysql_query(conn, query)) {
			fprintf(stderr, "插入失败：%s\n", mysql_error(conn));
			mysql_close(conn);
			return -1;
		}
		useropinfo->ID = (int)mysql_insert_id(conn);

		printf("注册成功\n");
	}
	//登录
	else {
		//用户表查找密文
		char encryptedPassWordExist[1024] = {0};
		memset(query, 0, sizeof(query));
		snprintf(query, sizeof(query), "SELECT encrypted_passWord FROM user_info WHERE username = '%s'", userName);
		if (mysql_query(conn, query)) {
			fprintf(stderr, "查找失败：%s\n", mysql_error(conn));
			mysql_close(conn);
			return -1;
		}
		res = mysql_store_result(conn);
		row = mysql_fetch_row(res);
		if (!row) {
			fprintf(stderr, "row获取结果失败: %s\n", mysql_error(conn));
		}

		while (1) {
			//接收密文
			memset(encryptedPassWord, 0, sizeof(encryptedPassWord));
			ret = recv(netfd, &packet.type, sizeof(packet.type), MSG_WAITALL);
			if (ret == 0) {
				printf("ret = 0, client已退出！\n");
				return -1;
			}
			ret = recv(netfd, &packet.length, sizeof(packet.length), MSG_WAITALL);
			if (ret == 0) {
				printf("ret = 0, client已退出！\n");
				return -1;
			}
			ret = recv(netfd, packet.value, packet.length, MSG_WAITALL);
			if (ret == 0) {
				printf("ret = 0, client已退出！\n");
				return -1;
			}
			memcpy(encryptedPassWord, packet.value, packet.length);

			memcpy(encryptedPassWordExist, row[0], strlen(row[0]) + 2);

			//找密文
			int loginFlag;
			if ((strcmp(encryptedPassWordExist, encryptedPassWord) == 0)) {
				loginFlag = 1;
			} else {
				loginFlag = -1;
			}
			send(netfd, &loginFlag, sizeof(int), MSG_NOSIGNAL); //发送登录密码是否正确
			if (loginFlag == 1) break;
		}
		//返回文件表的parentID
		memset(query, 0, sizeof(query));
		snprintf(query, sizeof(query), "SELECT id FROM file_info WHERE username = '%s'", userName);
		if (mysql_query(conn, query)) {
			fprintf(stderr, "查找失败：%s\n", mysql_error(conn));
			mysql_close(conn);
			return -1;
		}
		res = mysql_store_result(conn);
		row = mysql_fetch_row(res);
		if (!row) {
			fprintf(stderr, "row获取结果失败: %s\n", mysql_error(conn));
		}
		int id;
		id = atoi(row[0]);
		useropinfo->ID = id;
		printf("成功登录\n");

	}


	return 1;
}
